/************************************************************************/
/*    MainWindow: create is also initialization.                        */
/* If there are some errors in constructor,                             */
/* they will be the output of qWarning().                               */
/************************************************************************/

#include <QtGui>
#include "mainwindow.h"
#include "itemmodel.h"
#include "APnMView.h"

QString gElementDir;
QString gActorDir;
QString gRouterDir;
QString gPoolDir;
QString gCompositeDir;

static const QString actors = QString("actors.xml");
static const QString routers = QString("routers.xml");
static const QString pools = QString("pools.xml");
static const QString composites = QString("composites.xml");

MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{	
	readSettings();
	setWindowIcon(QIcon(":/Resources/logo.png"));
	setWindowTitle(tr("APnModel-IDE"));

	QSplitter *splitter = new QSplitter(this);
	splitter->setOrientation(Qt::Horizontal);
    
	//all items correspond with elements.
	QTabWidget *tabWidget = new QTabWidget(splitter);
	actorView = new QTreeView(tabWidget);
	loadModel(actorView, gElementDir+"/"+actors);
	routerView = new QTreeView(tabWidget);
	loadModel(routerView, gElementDir+"/"+routers); 
	poolView = new QTreeView(tabWidget);
	loadModel(poolView, gElementDir+"/"+pools);
	compositeView = new QTreeView(tabWidget);
	loadModel(compositeView, gElementDir+"/"+composites);
	tabWidget->addTab(actorView, "Actors");
	tabWidget->addTab(routerView, "Routers");
	tabWidget->addTab(poolView, "Pools");
	tabWidget->addTab(compositeView, "Composites");

	splitter->addWidget(tabWidget);

	mdiArea = new QMdiArea(splitter);
	QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	sizePolicy.setHorizontalStretch(1);
	sizePolicy.setVerticalStretch(0);
	mdiArea->setSizePolicy(sizePolicy);

	splitter->addWidget(mdiArea);
	
	setCentralWidget(splitter);

	/************************************************************************/
	/*                     normal operation of MDI                          */
	/************************************************************************/
	connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow *)),
		this, SLOT(updateMenus()));
	windowMapper = new QSignalMapper(this);
	connect(windowMapper, SIGNAL(mapped(QWidget *)),
		this, SLOT(setActiveSubWindow(QWidget *)));

	createActions();
	createMenus();
	createToolBars();
	createStatusBar();
	updateMenus();

	newFile();
}

MainWindow::~MainWindow() 
{ 
	DElementDelegate::destroy(); 
	if (runToolBar)
		delete runToolBar;
}

void MainWindow::closeEvent(QCloseEvent *event)
{
	mdiArea->closeAllSubWindows();
	if (activeAPnMView()) {
		event->ignore();
	} else {
		writeSettings();
		event->accept();
	}
}

void MainWindow::newFile()
{
	APnMView *child = createAPnMView();
	child->newFile();
	child->showMaximized();
}

void MainWindow::open()
{
	QString fileName = QFileDialog::getOpenFileName(this);
	if (!fileName.isEmpty()) {
		QString noSuffix = fileName;
		noSuffix.truncate(noSuffix.lastIndexOf('.'));

		openFile(noSuffix);
	}
}

void MainWindow::openFile(const QString & noSuffix)
{
	QMdiSubWindow *existing = findAPnMView(noSuffix);
	if (existing) {
		mdiArea->setActiveSubWindow(existing);
		return;
	}

	APnMView *child = createAPnMView();
	if (child->loadFile(noSuffix)) {
		statusBar()->showMessage(tr("File loaded"), 2000);
		child->show();
	} else {
		//Qt Examples: MDI have the same bug.
		//just close and delete itself, but the corresponding MdiSubWindow will still exist.
		//child->close();
		delete child->parentWidget();
	}
}

void MainWindow::save()
{
	if (activeAPnMView() && activeAPnMView()->save())
		statusBar()->showMessage(tr("File saved"), 2000);
}

void MainWindow::saveAs()
{
	if (activeAPnMView() && activeAPnMView()->saveAs())
		statusBar()->showMessage(tr("File saved"), 2000);
}

void MainWindow::print()
{
	if (activeAPnMView() && activeAPnMView()->print())
		statusBar()->showMessage(tr("Graph saved"), 2000);
}

void MainWindow::cut()
{
	if (activeAPnMView())
		activeAPnMView()->cut();
}

void MainWindow::copy()
{
	if (activeAPnMView())
		activeAPnMView()->copy();
}

void MainWindow::paste()
{
	if (activeAPnMView())
		activeAPnMView()->paste();
}

void MainWindow::del()
{
	if (activeAPnMView())
		activeAPnMView()->del();
}

//engine
void MainWindow::engineConf()
{
	mHost = mHostEdit->text();
	mPort = mPortEdit->text().toUInt();
}

// view on the Scientific Workflow Application
void MainWindow::compositeUp()
{
	if (activeAPnMView())
		activeAPnMView()->compositeUp();
}

void MainWindow::compositeDown()
{
	if (activeAPnMView())
		activeAPnMView()->compositeDown();
}

// control on the tokens in a Pool of the Scientific Workflow 
void MainWindow::setTokenMode(bool tokenMode)
{
	if (activeAPnMView()) {
		activeAPnMView()->setTokenMode(tokenMode);
		return; //a view exists, return
	}

	//no view, avoid recursion
	if (tokenMode != false) {
		tokenAct->setChecked(false);
	}
}

void MainWindow::tryEngine(bool connect)
{
	if (activeAPnMView()) {
		bool ok;
		if (connect) {
			ok = activeAPnMView()->upload();
			setRunMode(ok);
		}else {
			ok = activeAPnMView()->terminate();
			setRunMode(!ok);
		}
		return;
	}

	//no view
	engineAct->setChecked(false);
}

void MainWindow::setRunMode(bool runMode)
{
	if (runMode){
		addToolBar(runToolBar);
		runToolBar->show();
	}else 
		removeToolBar(runToolBar);
	
	engineAct->setChecked(runMode);
}

//control on the Scientific Workflow Application
void MainWindow::play()
{

}

void MainWindow::pause()
{

}

void MainWindow::stop()
{
}

void MainWindow::reverse_play()
{

}

void MainWindow::forward()
{

}

void MainWindow::backward()
{

}

/************************************************************************/
/*                                                                      */
/************************************************************************/

void MainWindow::about()
{
	QMessageBox::about(this, tr("About APnModel-IDE"), tr(
		 "<h3>About APnModel-IDE</h3>"
		 "<p>APnModel-IDE is an integrated development environment for developing "
		 "Scientific Workflow Applications based on <b>Actor Petri net Model</b>.</p>"
		 "<p> Actor Petri net Model is a simple model derived from Ptolemy II, "
		 "Petri nets, Nested Relational Calculus (maybe also DFL).</p>"
		 "<p>Desinger and Developer: Du Nanshan (email: dunanshan@163.com)</p>"
		 "<p>Institution: School of Computer, Wuhan University & "
		 "Shenzhen Research Institute, City University of Hong Kong<p>"
		 "<p>See <a href=\"http://sites.google.com/site/dunanshan\">googleweb/site/dunanshan</a>"
		 " and <a href=\"http://code.google.com/p/actor-petri-net-model-ide/\">googlecode/APnModel</a>"
		 "for more information.</p>"
		));
}

void MainWindow::updateMenus()
{
	bool hasGraphicsView = (activeAPnMView() != 0);
	saveAct->setEnabled(hasGraphicsView);
	saveAsAct->setEnabled(hasGraphicsView);
	pasteAct->setEnabled(hasGraphicsView);
	closeAct->setEnabled(hasGraphicsView);
	closeAllAct->setEnabled(hasGraphicsView);
	tileAct->setEnabled(hasGraphicsView);
	cascadeAct->setEnabled(hasGraphicsView);
	nextAct->setEnabled(hasGraphicsView);
	previousAct->setEnabled(hasGraphicsView);
	separatorAct->setVisible(hasGraphicsView);

	bool hasSelection = (activeAPnMView() &&
		activeAPnMView()->hasSelection());
	cutAct->setEnabled(hasSelection);
	copyAct->setEnabled(hasSelection);
	delAct->setEnabled(hasSelection);

	tokenAct->setChecked(activeAPnMView() && activeAPnMView()->tokenMode());
	setRunMode(activeAPnMView() && activeAPnMView()->runMode());
}

void MainWindow::updateWindowMenu()
{
	windowMenu->clear();
	windowMenu->addAction(closeAct);
	windowMenu->addAction(closeAllAct);
	windowMenu->addSeparator();
	windowMenu->addAction(tileAct);
	windowMenu->addAction(cascadeAct);
	windowMenu->addSeparator();
	windowMenu->addAction(nextAct);
	windowMenu->addAction(previousAct);
	windowMenu->addAction(separatorAct);

	QList<QMdiSubWindow *> windows = mdiArea->subWindowList();
	separatorAct->setVisible(!windows.isEmpty());

	for (int i = 0; i < windows.size(); ++i) {
		APnMView *child = qobject_cast<APnMView *>(windows.at(i)->widget());

		QString text;
		if (i < 9) {
			text = tr("&%1 %2").arg(i + 1)
				.arg(child->userFriendlyCurrentFile());
		} else {
			text = tr("%1 %2").arg(i + 1)
				.arg(child->userFriendlyCurrentFile());
		}
		QAction *action  = windowMenu->addAction(text);
		action->setCheckable(true);
		action ->setChecked(child == activeAPnMView());
		connect(action, SIGNAL(triggered()), windowMapper, SLOT(map()));
		windowMapper->setMapping(action, windows.at(i));
	}
}

APnMView *MainWindow::createAPnMView()
{
	APnMView *child = new APnMView(mdiArea);
	mdiArea->addSubWindow(child);

	connect(child, SIGNAL(openFile(const QString &)), this, SLOT(openFile(const QString &)));

	connect(child, SIGNAL(copyAvailable(bool)),
		cutAct, SLOT(setEnabled(bool)));
	connect(child, SIGNAL(copyAvailable(bool)),
		copyAct, SLOT(setEnabled(bool)));
	connect(child, SIGNAL(copyAvailable(bool)),
		delAct, SLOT(setEnabled(bool)));

	return child;
}

void MainWindow::createActions()
{
	newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this);
	newAct->setShortcut(tr("Ctrl+N"));
	newAct->setStatusTip(tr("Create a new file"));
	connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));

	openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
	openAct->setShortcut(tr("Ctrl+O"));
	openAct->setStatusTip(tr("Open an existing file"));
	connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

	saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this);
	saveAct->setShortcut(tr("Ctrl+S"));
	saveAct->setStatusTip(tr("Save the document to disk"));
	connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));

	saveAsAct = new QAction(tr("Save &As..."), this);
	saveAsAct->setStatusTip(tr("Save the document under a new name"));
	connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));

	printAct = new QAction(QIcon(":/images/print.png"), tr("&Print..."), this);
	printAct->setShortcut(tr("Ctrl+P"));
	printAct->setStatusTip(tr("Print the document"));
	connect(printAct, SIGNAL(triggered()), this, SLOT(print()));

	exitAct = new QAction(QIcon(":/images/exit.png"), tr("E&xit"), this);
	exitAct->setShortcut(tr("Ctrl+Q"));
	exitAct->setStatusTip(tr("Exit the application"));
	connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));

	cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);
	cutAct->setShortcut(tr("Ctrl+X"));
	cutAct->setStatusTip(tr("Cut the current selection's contents to the "
		"clipboard"));
	connect(cutAct, SIGNAL(triggered()), this, SLOT(cut()));

	copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this);
	copyAct->setShortcut(tr("Ctrl+C"));
	copyAct->setStatusTip(tr("Copy the current selection's contents to the "
		"clipboard"));
	connect(copyAct, SIGNAL(triggered()), this, SLOT(copy()));

	pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this);
	pasteAct->setShortcut(tr("Ctrl+V"));
	pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current "
		"selection"));
	connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste()));

	delAct = new QAction(QIcon(":/images/delete.png"), tr("&Delete"), this);
	delAct->setShortcut(tr("Ctrl+D"));
	delAct->setStatusTip(tr("Delete the current selection's contents"));
	connect(delAct, SIGNAL(triggered()), this, SLOT(del()));

	
	//APnModel Engine Config
	
	//APnModel Actions
	upAct = new QAction(QIcon(":/images/control/up.png"), tr("&Up"), this);
	upAct->setShortcut(tr("Ctrl+U"));
	upAct->setStatusTip(tr("Show the current composite's parent composite"));
	connect(upAct, SIGNAL(triggered()), this, SLOT(compositeUp()));

	downAct = new QAction(QIcon(":/images/control/down.png"), tr("Dow&n"), this);
	downAct->setShortcut(tr("Ctrl+N"));
	downAct->setStatusTip(tr("Show the details of current composite"));
	connect(downAct, SIGNAL(triggered()), this, SLOT(compositeDown()));

	tokenAct = new QAction(QIcon(":/images/control/token.png"), tr("&Token"), this);
	tokenAct->setCheckable(true);
	tokenAct->setShortcut(tr("Ctrl+T"));
	tokenAct->setStatusTip(tr("Enter into Token Edit Mode"));
	connect(tokenAct, SIGNAL(toggled(bool)), this, SLOT(setTokenMode(bool)));

	engineAct = new QAction(QIcon(":/images/control/engine.png"), tr("&Upload"), this);
	engineAct->setCheckable(true);
	engineAct->setShortcut(tr("Ctrl+U"));
	engineAct->setStatusTip(tr("Upload the Scientific Workflow Application to a Engine"));
	connect(engineAct, SIGNAL(triggered(bool)), this, SLOT(tryEngine(bool)));

	//run control
	playAct = new QAction(QIcon(":/images/control/play.png"), tr("&Play"), this);
	playAct->setShortcut(tr("Ctrl+P"));
	playAct->setStatusTip(tr("Run and Simulate the current appliction"));
	connect(playAct, SIGNAL(triggered()), this, SLOT(play()));

	pauseAct = new QAction(QIcon(":/images/control/pause.png"), tr("Pa&use"), this);
	pauseAct->setShortcut(tr("Ctrl+U"));
	pauseAct->setStatusTip(tr("Pause the current appliction"));
	connect(pauseAct, SIGNAL(triggered()), this, SLOT(pause()));

	stopAct = new QAction(QIcon(":/images/control/stop.png"), tr("&Stop"), this);
	stopAct->setShortcut(tr("Ctrl+S"));
	stopAct->setStatusTip(tr("Stop the current appliction"));
	connect(stopAct, SIGNAL(triggered()), this, SLOT(play()));

	reverse_playAct = new QAction(QIcon(":/images/control/reverse_play.png"), tr("&Reverse Play"), this);
	reverse_playAct->setShortcut(tr("Ctrl+R"));
	reverse_playAct->setStatusTip(tr("Reverse Run and Simulate the current appliction"));
	connect(reverse_playAct, SIGNAL(triggered()), this, SLOT(reverse_play()));

	forwardAct = new QAction(QIcon(":/images/control/forward.png"), tr("&Forward"), this);
	forwardAct->setShortcut(tr("Ctrl+F"));
	forwardAct->setStatusTip(tr(" Step One Run and Simulate the current appliction"));
	connect(forwardAct, SIGNAL(triggered()), this, SLOT(forward()));

	backwardAct = new QAction(QIcon(":/images/control/backward.png"), tr("&Backward"), this);
	backwardAct->setShortcut(tr("Ctrl+B"));
	backwardAct->setStatusTip(tr("Step One Back Run and Simulate the current appliction"));
	connect(backwardAct, SIGNAL(triggered()), this, SLOT(backward()));

	/************************************************************************/
	/*                                                                      */
	/************************************************************************/

	closeAct = new QAction(tr("Cl&ose"), this);
	closeAct->setShortcut(tr("Ctrl+W"));
	//closeAct->setShortcut(tr("Ctrl+F4"));//default: Ctrl+F4   if set it again, it will not work.
	closeAct->setStatusTip(tr("Close the active window"));
	connect(closeAct, SIGNAL(triggered()),
		mdiArea, SLOT(closeActiveSubWindow()));

	closeAllAct = new QAction(tr("Close &All"), this);
	closeAllAct->setStatusTip(tr("Close all the windows"));
	connect(closeAllAct, SIGNAL(triggered()),
		mdiArea, SLOT(closeAllSubWindows()));

	tileAct = new QAction(tr("&Tile"), this);
	tileAct->setStatusTip(tr("Tile the windows"));
	connect(tileAct, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows()));

	cascadeAct = new QAction(tr("&Cascade"), this);
	cascadeAct->setStatusTip(tr("Cascade the windows"));
	connect(cascadeAct, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows()));

	nextAct = new QAction(tr("Ne&xt"), this);
	nextAct->setStatusTip(tr("Move the focus to the next window"));
	connect(nextAct, SIGNAL(triggered()),
		mdiArea, SLOT(activateNextSubWindow()));

	previousAct = new QAction(tr("Pre&vious"), this);
	previousAct->setStatusTip(tr("Move the focus to the previous window"));
	connect(previousAct, SIGNAL(triggered()),
		mdiArea, SLOT(activatePreviousSubWindow()));

	separatorAct = new QAction(this);
	separatorAct->setSeparator(true);

	aboutAct = new QAction(QIcon(":/images/fly.png"), tr("&About"), this);
	aboutAct->setStatusTip(tr("Show the application's About box"));
	connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));

	aboutQtAct = new QAction(QIcon(":/images/qt-logo.png"), tr("About &Qt"), this);
	aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
	connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
}

void MainWindow::createMenus()
{
	fileMenu = menuBar()->addMenu(tr("&File"));
	fileMenu->addAction(newAct);
	fileMenu->addAction(openAct);
	fileMenu->addAction(saveAct);
	fileMenu->addAction(saveAsAct);
	fileMenu->addAction(printAct);
	fileMenu->addSeparator();
	fileMenu->addAction(exitAct);

	editMenu = menuBar()->addMenu(tr("&Edit"));
	editMenu->addAction(cutAct);
	editMenu->addAction(copyAct);
	editMenu->addAction(pasteAct);
	editMenu->addAction(delAct);

	//control
	apnmMenu = menuBar()->addMenu(tr("&APnModel"));
	//apnmMenu->addAction(upAct);
	apnmMenu->addAction(downAct);
	apnmMenu->addSeparator();
	apnmMenu->addAction(tokenAct);
	apnmMenu->addSeparator();
	apnmMenu->addAction(engineAct);

	/************************************************************************/
	/*                                                                      */
	/************************************************************************/

	windowMenu = menuBar()->addMenu(tr("&Window"));
	updateWindowMenu();
	connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu()));

	helpMenu = menuBar()->addMenu(tr("&Help"));
	helpMenu->addAction(aboutAct);
	helpMenu->addAction(aboutQtAct);
}

void MainWindow::createToolBars()
{
	fileToolBar = addToolBar(tr("File"));
	fileToolBar->addAction(newAct);
	fileToolBar->addAction(openAct);
	fileToolBar->addAction(saveAct);
	fileToolBar->addAction(printAct);

	editToolBar = addToolBar(tr("Edit"));
	editToolBar->addAction(cutAct);
	editToolBar->addAction(copyAct);
	editToolBar->addAction(pasteAct);
	editToolBar->addAction(delAct);

	//can be deleted**********
	QAction* expand = new QAction(tr("&Expand"), this);
	expand->setShortcut(tr("Ctrl+E"));
	expand->setToolTip(tr("Ctrl+E"));
	connect(expand, SIGNAL(triggered()), actorView, SLOT(expandAll()));
	connect(expand, SIGNAL(triggered()), routerView, SLOT(expandAll()));
	connect(expand, SIGNAL(triggered()), poolView, SLOT(expandAll()));
	connect(expand, SIGNAL(triggered()), compositeView, SLOT(expandAll()));
	editToolBar->addAction(expand);

	//QAction* test = new QAction(tr("&Test"), this);
	//connect(test, SIGNAL(triggered()), this, SLOT(test()));
	//test->setShortcut(tr("Ctrl+T"));
	//test->setToolTip(tr("Ctrl+T"));
	//editToolBar->addAction(test);
	//************************

	//control
	apnmToolBar = addToolBar(tr("Control"));
	//apnmToolBar->addAction(upAct);
	apnmToolBar->addAction(downAct);
	apnmToolBar->addSeparator();
	apnmToolBar->addAction(tokenAct);
	apnmToolBar->addSeparator();
	apnmToolBar->addAction(engineAct);

	runToolBar = new QToolBar("Run Mode");
	runToolBar->addAction(playAct);
	runToolBar->addAction(pauseAct);
	runToolBar->addAction(stopAct);
	runToolBar->addAction(reverse_playAct);
	runToolBar->addAction(forwardAct);
	runToolBar->addAction(backwardAct);

	//configure engine host and port
	engineToolBar = addToolBar(tr("Engine"));
	engineToolBar->addWidget(new QLabel(tr("Host:"), this));
	mHostEdit = new QLineEdit(this);
	mHostEdit->setText(mHost);
	connect(mHostEdit, SIGNAL(textChanged( const QString& )), this, SLOT(engineConf()) );
	engineToolBar->addWidget(mHostEdit);
	engineToolBar->addWidget(new QLabel(tr(" Port:"), this));
	mPortEdit = new QLineEdit(this);
	mPortEdit->setText(QString("%1").arg(mPort));
	mPortEdit->setValidator(new QIntValidator(1025, 65535, this));
	connect(mPortEdit, SIGNAL(textChanged( const QString& )), this, SLOT(engineConf()) );
	engineToolBar->addWidget(mPortEdit);
}

void MainWindow::test()
{
	//activeAPnMView()->addTextItem();
}

void MainWindow::createStatusBar()
{
	statusBar()->showMessage(tr("Ready"));
}


//Basic settings of APnModel-IDE, corresponding with file APnMIDE.ini
//Every folder contains a kind of element descriptions.
//Elements are Actor, Router, Pool, Composite, respectively.
void MainWindow::readSettings()
{
	QSettings settings("APnMIDE.ini", QSettings::IniFormat);
	QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
	QSize size = settings.value("size", QSize(800, 600)).toSize();
	move(pos);
	resize(size);

	mHost = settings.value("Host", QString("Localhost")).toString();
	mPort = settings.value("Port", 5712).toUInt();

	gElementDir = settings.value("elementDir", "elements").toString();
	gActorDir = settings.value("actorDir", "elements/Actors").toString();
	gRouterDir = settings.value("routerDir", "elements/Routers").toString();
	gPoolDir = settings.value("poolDir", "elements/Pools").toString();
	gCompositeDir = settings.value("compositeDir", "elements/Composites").toString();
}

void MainWindow::writeSettings()
{
	QSettings settings("APnMIDE.ini", QSettings::IniFormat);
	settings.setValue("pos", pos());
	settings.setValue("size", size());

	settings.setValue("Host", mHost);
	settings.setValue("Port", mPort);

	settings.setValue("elementDir", gElementDir);
	settings.setValue("actorDir", gActorDir);
	settings.setValue("routerDir", gRouterDir);
	settings.setValue("poolDir", gPoolDir);
	settings.setValue("compositeDir", gCompositeDir);
}

APnMView *MainWindow::activeAPnMView()
{
	if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow())
		return qobject_cast<APnMView *>(activeSubWindow->widget());
	return 0;
}

QMdiSubWindow *MainWindow::findAPnMView(const QString &fileName)
{
	//QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();

	foreach (QMdiSubWindow *window, mdiArea->subWindowList()) {
		APnMView *mdiChild = qobject_cast<APnMView *>(window->widget());
		if (mdiChild->currentFile() == fileName)
			return window;
	}
	return 0;
}

void MainWindow::setActiveSubWindow(QWidget *window)
{
	if (!window)
		return;
	mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window));
} 
// load model value, respectively(actor, router, and pool) 
bool MainWindow::loadModel(QTreeView* view, const QString& file)
{
	ItemModel *model = new ItemModel( this );
	if ( !model->loadData( file ) )
		return false;
	
	view->setModel(model);
	view->header()->hide();
	view->setDragEnabled(true);
	view->setSelectionMode(QAbstractItemView::ExtendedSelection);
	return true;	
}
